home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / julin105.zip / JULIAN.C < prev   
C/C++ Source or Header  |  1993-08-02  |  8KB  |  433 lines

  1.  
  2. /********************************************************************
  3.  *                                                                  *
  4.  *        JULIAN DATE LIBRARY (c)Copyright 1992 by CalcShop Inc.      *
  5.  *                      All rights reserved.                          *
  6.  *                                                                  *
  7.  *                 JULIAN v1.05 d08/02/93                           *
  8.  *                                                                  *
  9.  *                                                                  *
  10.  *                         Robert Emmons                              *
  11.  *                         CalcShop Inc.                              *
  12.  *                          P.O Box 1231                              *
  13.  *                     W. Caldwell, NJ  07007                         *
  14.  *             Phones: (201)228-9139 or (800)466-3469                 *
  15.  *                                                                  *
  16.  ********************************************************************/
  17.  
  18.  
  19.  
  20. #include <stdlib.h>
  21. #include <math.h>
  22. #include <ctype.h>
  23. #include <stdio.h>        /* for sprintf() */
  24. #include "juldef.h"
  25.  
  26.  
  27.  
  28.  
  29. /*
  30. **************************************************************************
  31.  
  32.     These functions convert from Gregorian dates to Julian day numbers
  33.  
  34. **************************************************************************
  35. */
  36.  
  37.  
  38. long gregtojday(GDATE gdate)
  39. {
  40.     int prvyear, leaps;
  41.     long jday;
  42.  
  43.     /*
  44.         gregtojday calculates the julian day number for a date, using
  45.         JAN 1 0001 AD as day number 1.
  46.         gregtojday works from JAN 1 0001 AD ad infinatum, ignoring the
  47.         unusual calendar modifications which were sometimes used
  48.         in the past.
  49.     */
  50.  
  51.     /* calc the number of leap years which preceeded the current year */
  52.     prvyear = gdate.year - 1;
  53.     leaps = prvyear / 4 - prvyear / 100 + prvyear / 400;
  54.  
  55.     /* calc julian day number */
  56.     jday = gregtoyday(gdate);        /* calc day of year    */
  57.     if(jday > BADDATE)
  58.         jday += (long)prvyear * 365l + (long)leaps;
  59.     return(jday);
  60. }
  61.  
  62.  
  63. int gregtoyday(GDATE gdate)
  64. {
  65.     int yday, leapyear;
  66.  
  67.     /*
  68.         gregtoyday calculates the julian day for a date,
  69.         using JAN 1 of the current year as day number 1.
  70.     */
  71.  
  72.     leapyear = isleap(gdate.year);     /* returns TRUE or FALSE */
  73.  
  74.     /* check # days in month */
  75.     if(gdate.day <= 0)
  76.         return(BADDAY);
  77.     switch(gdate.month)
  78.     {
  79.     case 1:
  80.     case 3:
  81.     case 5:
  82.     case 7:
  83.     case 8:
  84.     case 10:
  85.     case 12:
  86.         if(gdate.day > 31)
  87.             return(BADDAY);
  88.         break;
  89.     case 2:
  90.         if(gdate.day > 29)
  91.             return(BADDAY);
  92.         else if(leapyear == FALSE && gdate.day > 28)
  93.             return(BADDAY);
  94.         break;
  95.     case 4:
  96.     case 6:
  97.     case 9:
  98.     case 11:
  99.         if(gdate.day > 30)
  100.             return(BADDAY);
  101.         break;
  102.     default:
  103.         return(BADMONTH);
  104.     }
  105.  
  106.     switch(gdate.month)
  107.     {
  108.     default:
  109.         yday = BADMONTH;
  110.         break;
  111.     case 1:
  112.         yday = gdate.day;
  113.         break;
  114.     case 2:
  115.         yday = gdate.day + 31;
  116.         break;
  117.     case 3:
  118.         yday = gdate.day + 59;
  119.         break;
  120.     case 4:
  121.         yday = gdate.day + 90;
  122.         break;
  123.     case 5:
  124.         yday = gdate.day + 120;
  125.         break;
  126.     case 6:
  127.         yday = gdate.day + 151;
  128.         break;
  129.     case 7:
  130.         yday = gdate.day + 181;
  131.         break;
  132.     case 8:
  133.         yday = gdate.day + 212;
  134.         break;
  135.     case 9:
  136.         yday = gdate.day + 243;
  137.         break;
  138.     case 10:
  139.         yday = gdate.day + 273;
  140.         break;
  141.     case 11:
  142.         yday = gdate.day + 304;
  143.         break;
  144.     case 12:
  145.         yday = gdate.day + 334;
  146.         break;
  147.     }
  148.  
  149.     /* check year */
  150.     if(gdate.year < 0)
  151.         return(BADYEAR);
  152.  
  153.     if(leapyear == TRUE && gdate.month != 1 && gdate.month != 2)
  154.         ++yday;
  155.  
  156.     return(yday);
  157. }
  158.  
  159.  
  160. double gregtojear(GDATE gdate)
  161. {
  162.     return(gregtojday(gdate) / AVYRDAYS + 1.0);
  163. }
  164.  
  165.  
  166.  
  167.  
  168.  
  169. /*
  170. **************************************************************************
  171.  
  172.     These functions convert from Julian day numbers to Gregorian dates
  173.  
  174. **************************************************************************
  175. */
  176.  
  177.  
  178. GDATE jdaytogreg(long jday)
  179. {
  180.     GDATE gdate;
  181.  
  182.     /* calc year and yearday */
  183.     gdate = jdaytoyday(jday);
  184.  
  185.     /* calc month and day */
  186.     gdate = ydaytogreg(gdate.day, gdate.year);
  187.  
  188.     return(gdate);
  189. }
  190.  
  191.  
  192. GDATE jdaytoyday(long jday)
  193. {
  194.  
  195.     int quadcents, remcents, remquads, remyears;
  196.     GDATE gdate;
  197.  
  198.     gdate.month = BADMONTH;    /* dummy value */
  199.  
  200.     quadcents = jday / QCENTDAYS;
  201.     jday -= QCENTDAYS * quadcents;
  202.     if(jday < 1){
  203.     gdate.year = 400 * quadcents;
  204.         gdate.day = YEARDAYS + 1;
  205.         return gdate;
  206.     }
  207.  
  208.     remcents = jday / CENTDAYS;
  209.     jday -= CENTDAYS * remcents;
  210.     if(jday < 1){
  211.     gdate.year = 400 * quadcents + 100 * remcents;
  212.         gdate.day = YEARDAYS;
  213.         return gdate;
  214.     }
  215.  
  216.     remquads = jday / QUADDAYS;
  217.     jday -= QUADDAYS * remquads;
  218.     if(jday < 1){
  219.     gdate.year = 400 * quadcents + 100 * remcents + 4 * remquads;
  220.         gdate.day = YEARDAYS + 1;
  221.         return gdate;
  222.     }
  223.  
  224.     remyears = jday / YEARDAYS;
  225.     jday -= YEARDAYS * remyears;
  226.     if(jday < 1){
  227.     gdate.year = 400 * quadcents + 100 * remcents
  228.                  + 4 * remquads + remyears;
  229.         gdate.day = YEARDAYS;
  230.         return gdate;
  231.     }
  232.  
  233.     gdate.year = 1 + 400 * quadcents + 100 * remcents
  234.                  + 4 * remquads + remyears;
  235.     gdate.day = jday;
  236.     return gdate;
  237. }
  238.  
  239.  
  240. GDATE ydaytogreg(int yday, int year)
  241. {
  242.     int leap;
  243.     GDATE gdate;
  244.  
  245.     gdate.year = year;
  246.     leap = isleap(gdate.year);
  247.     if(yday < 1)
  248.     {
  249.         gdate.month = 12;
  250.         gdate.day = 31;
  251.     }
  252.     else if(yday <= 31)
  253.     {
  254.         gdate.month = 1;
  255.         gdate.day = yday;
  256.     }
  257.     else if(yday <= leap + 59)
  258.     {
  259.         gdate.month = 2;
  260.         gdate.day = yday - 31;
  261.     }
  262.     else if(yday <= leap + 90)
  263.     {
  264.         gdate.month = 3;
  265.         gdate.day = yday - leap - 59;
  266.     }
  267.     else if(yday <= leap + 120)
  268.     {
  269.         gdate.month = 4;
  270.         gdate.day = yday - leap - 90;
  271.     }
  272.     else if(yday <= leap + 151)
  273.     {
  274.         gdate.month = 5;
  275.         gdate.day = yday - leap - 120;
  276.     }
  277.     else if(yday <= leap + 181)
  278.     {
  279.         gdate.month = 6;
  280.         gdate.day = yday - leap - 151;
  281.     }
  282.     else if(yday <= leap + 212)
  283.     {
  284.         gdate.month = 7;
  285.         gdate.day = yday - leap - 181;
  286.     }
  287.     else if(yday <= leap + 243)
  288.     {
  289.         gdate.month = 8;
  290.         gdate.day = yday - leap - 212;
  291.     }
  292.     else if(yday <= leap + 273)
  293.     {
  294.         gdate.month = 9;
  295.         gdate.day = yday - leap - 243;
  296.     }
  297.     else if(yday <= leap + 304)
  298.     {
  299.         gdate.month = 10;
  300.         gdate.day = yday - leap - 273;
  301.     }
  302.     else if(yday <= leap + 334)
  303.     {
  304.         gdate.month = 11;
  305.         gdate.day = yday - leap - 304;
  306.     }
  307.     else
  308.     {
  309.         gdate.month = 12;
  310.         gdate.day = yday - leap - 334;
  311.     }
  312.  
  313.     return(gdate);
  314. }
  315.  
  316.  
  317. GDATE jeartogreg(double jear)
  318. {
  319.     return(jdaytogreg((long)((jear - 1) * AVYRDAYS + .5)));
  320. }
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328. /*
  329. **************************************************************************
  330.  
  331.     These functions convert between string and gregorian
  332.  
  333. **************************************************************************
  334. */
  335.  
  336.  
  337. GDATE mmddyyyytogreg(char *chrp, int nearyear)
  338. {
  339.     GDATE gdate;
  340.  
  341.     /*
  342.         mmddyyyytogreg() changes a null terminated string
  343.         to a gregorain GDATE format date.
  344.     */
  345.  
  346.     /* convert month */
  347.     gdate.month = atoi(chrp);
  348.  
  349.     /* find and convert day */
  350.     while(isdigit(*chrp++));        /* skip to next non-digit plus one */
  351.     gdate.day = atoi(chrp);
  352.  
  353.     /* find and convert year */
  354.     while(isdigit(*chrp++));        /* skip to next non-digit plus one */
  355.     gdate.year = yytoyear(chrp, nearyear);
  356.  
  357.     return(gdate);
  358. }
  359.  
  360.  
  361. int yytoyear(char *str, int nearyear)
  362. {
  363.     char *digitp;
  364.     int year;
  365.  
  366.     digitp = str;
  367.     while(isdigit(*digitp++));        /* skip to next non-digit plus one */
  368.     if(nearyear > 0 && digitp - str <= 3){
  369.         year = atoi(str) + (nearyear - MAXYY) / 100 * 100;
  370.         if(abs(nearyear - year) >= MAXYY)
  371.             year += 100;
  372.     }
  373.     else
  374.         year = atoi(str);
  375.  
  376.     return(year);
  377. }
  378.  
  379.  
  380. char *gregtommddyyyy(char *str, GDATE gdate, int nearyear)
  381. {
  382.     int diff;
  383.  
  384.     diff = abs(gdate.year - nearyear);
  385.     if(nearyear <= 0 || diff > MAXYY)
  386.         /* output 4 digits */
  387.         sprintf
  388.         (
  389.             str, "%02d/%02d/%04d", gdate.month, gdate.day, gdate.year
  390.         );
  391.     else
  392.         /* output 2 digits */
  393.         sprintf
  394.         (
  395.             str, "%02d/%02d/%02d", gdate.month, gdate.day, gdate.year % 100
  396.         );
  397.     return str;
  398. }
  399.  
  400.  
  401.  
  402.  
  403.  
  404.  
  405.  
  406.  
  407. /*
  408. **************************************************************************
  409.  
  410.     These are additional date related functions
  411.  
  412. **************************************************************************
  413. */
  414.  
  415.  
  416. int isleap(int year)
  417. {
  418.     if(year %